package executors

import scala.collection.mutable.LinkedList
import client_updater.Update
import org.hibernate.{Session, SessionFactory}
import org.hibernate.cfg.Configuration
import db.File
import db.FileManager
import db.Folder
import db.FolderManager
import db.User
import db.Client
import client_updater.ClientsUpdater
import objects.File1
import scala.actors.Actor

/**
 * Processes an update about a file that was deleted in a client's dropbox.<br>
 * communicates with the database and sends updates for other clients.
 */
class DeletedFileExecutor extends Actor{

  /**
   * the acting method of the actor
   */
  def act(){
    loop{
      react{
        case (deletedFile : File1)=> execute(deletedFile)
        case "Quit" => exit()
        case _ => println("DeletedFileExecutor received unknown message")
      }
    }
  }
  
  /**
   * receives a File1 that contains details about a file that was deleted in a client's dropbox.<br>
   * communicates with the database and the disk, and sends updates for other clients.<br>
   * @param - deletedFile : File1, details about the deleted file
   */
  private def execute(deletedFile: File1) {
    val cfg = new Configuration()
    var sessionFactory = null.asInstanceOf[SessionFactory]
    var session = null.asInstanceOf[Session]
    try{
    sessionFactory = cfg.configure().buildSessionFactory()
    session = sessionFactory.openSession()
    //get files with the given id from database
    var query = session.createQuery("from File f where f.fileName = '" + deletedFile.name +
      "' and parent_folder = " + deletedFile.parent)
    val fileInstances = query.list().toArray
    if (fileInstances.isEmpty) {
      return;
    }
    query = session.createQuery("from Folder f where f.folderID = " + deletedFile.parent)
    //get the folder from the database in order to know who the users are
    val folderUsers = query.list().toArray
    val fileManager = new FileManager(session)

    var clients = new LinkedList[Client]
    //collects all relevant clients
    for( f <- folderUsers ){
      query = session.createQuery("from Clients where user_ID = " + f.asInstanceOf[Folder].getUserID )
      var newClients = query.list().toArray
      for( c <- newClients ){
        clients = clients :+ c.asInstanceOf[Client]
      }
    }
    
    /*folderUsers.foreach(f => {
      query = session.createQuery("from Clients where user_ID = '" + f.getUserID + "'")
      var newClients = query.list().asInstanceOf[List[Client]]
      clients.addAll(newClients)
    })*/

    var curFile = fileInstances.first.asInstanceOf[File]

    if (fileInstances.size == 1) {
      //delete actual file from disk
      val file = new java.io.File("storage\\" + curFile.getFileID)
      file.delete
    }

    val client = new Client
    client.setUserID(deletedFile.uid)
    client.setClientID(deletedFile.cid)
    //adds an update for each client
    for( c <- clients ){
      if( c != client ){
        ClientsUpdater.addUpdate(c.getClientID, new Update("deletedFile", curFile.getFileName, curFile.getParentFolder))
      }
    }
    /*clients.foreach(c => {
      if (c != client) {
        var update = new FileUpdate("deleted file", c, curFile)
        ClientsUpdater.addUpdate(update)
      }
    })*/
    session.flush
    } catch { case (e : Exception) => println(e.printStackTrace) }
  }
    
}